/**
 * Copyright 2014 wasu.com
 *
 *
 * Create on 2015-1-6 下午6:50:49
 */
package xiaojian.toolkit.jms.actor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;

import xiaojian.toolkit.ebus.EventBus;
import xiaojian.toolkit.ebus.actors.AbstractEventActor;
import xiaojian.toolkit.jms.DestinationJMSMessgeSender;
import xiaojian.toolkit.util.ClosureEx;

/**
 * event:target.q.name，事件对应队列名称。这样直接通过事件就能把消息发送出去。
 * 
 * @author <a href="mailto:caoxiaojian@wasu.com>xiaojian.cao</a>
 * 
 */
public abstract class JMSMessageSenderEventActor extends AbstractEventActor {

	private static final Logger logger = LoggerFactory
			.getLogger(JMSMessageSenderEventActor.class);

	/**
	 * @param ebus
	 * @param name
	 */
	public JMSMessageSenderEventActor(EventBus ebus, String name) {
		super(ebus, name);
	}

	private List<Runnable> dtors = new ArrayList<Runnable>();

	private Map<String, ClosureEx> closures = new HashMap<String, ClosureEx>();

	public Map<String, ClosureEx> getClosures() {
		return Collections.unmodifiableMap(closures);
	}

	public Map<String, String> getEventsMap() {
		Map<String, String> ret = new HashMap<String, String>();
		for (Map.Entry<String, ClosureEx> entry : this.closures.entrySet()) {
			ret.put(entry.getKey(), entry.getValue().toString());
		}

		return ret;
	}

	public void setEvents(List<String> events) {
		Preconditions.checkArgument(events != null && events.size() > 0);

		this.closures.clear();

		for (String event : events) {
			String[] strs = StringUtils.split(event, ":");

			if (strs.length != 2) {
				logger.error("Invalid event[" + event + "].");
				continue;
			}

			DestinationJMSMessgeSender sender = createJmsMessgeSender();
			sender.setTargetName(strs[1]);
			MessageSendFunctor functor = new MessageSendFunctor(sender);
			this.closures.put(strs[0], functor);

			logger.debug("Add event[" + strs[0] + "] <-> [" + functor + "].");

		}
	}

	public abstract DestinationJMSMessgeSender createJmsMessgeSender();

	public void start() {
		for (Map.Entry<String, ClosureEx> entry : this.closures.entrySet()) {
			String event = entry.getKey();
			logger.debug("Add event[" + event + "] to eventbus.");
			dtors.add(registerObserver(event, entry.getValue()));
		}
	}

	public void destroy() {
		for (Runnable canceler : dtors) {
			try {
				canceler.run();
			} catch (Exception e) {
				logger.error("destroy:", e);
			}
		}
		dtors.clear();

		super.destroy();
	}

}
